package com.vshop.controller.login;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.vshop.entity.interfacerequest.ExceptionRequest;
import com.vshop.entity.interfacerequest.userlogin.request.RequestUserLogin;
import com.vshop.entity.interfacerequest.userlogin.request.RequestUserLoginData;
import com.vshop.entity.interfacerequest.userlogin.request.RequestUserLoginTradeData;
import com.vshop.entity.interfacerequest.userlogin.response.ResponseUserLogin;
import com.vshop.entity.requestinterface.Constant;
import com.vshop.entity.requestinterface.usercardorder.querydevicerealtime.request.RequestQueryDeviceRealTimeNew;
import com.vshop.entity.requestinterface.usercardorder.querydevicerealtime.response.ResponseQueryDeviceRealTime;
import com.vshop.entity.requestinterface.usercardorder.querydevicerealtime.response.ResponseQueryDeviceRealTimeTradeData;
import com.vshop.entity.requestinterface.userlogin.request.UserLoginRequest;
import com.vshop.entity.requestinterface.userlogin.response.UserLoginResponse;
import com.vshop.service.PartnerInfoService;
import com.vshop.service.SequenceService;
import com.vshop.service.agatewaytobeijing.GatewayToBeijingService;
import com.vshop.service.impl.PurchaseLogicService;
import com.vshop.utils.HttpUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 有卡登录
 *
 * @author lm
 * @date 2019/03/07
 */
@RestController
@Api(description = "有卡登录")
@Slf4j
public class UserCardLoginController {
    /**
     * 直接请求网关xml接口的地址
     */
    @Value("${iot.requestURI}")
    private String requestURI;
    @Autowired
    PurchaseLogicService purchaseService;
    @Autowired
    private SequenceService sequenceService;
    @Autowired
    private PartnerInfoService partnerInfoService;
    /**
     * 请求网关的服务类
     */
    @Autowired
    GatewayToBeijingService toBeijingService;

    @CrossOrigin
    @PostMapping(value = "userLogin", produces = "application/json;charset=utf-8")
    @ResponseBody
    @ApiOperation(value = "有卡登录", response = ResponseUserLogin.class)
    public String userLogin(@ApiParam @RequestBody RequestUserLogin request) {
        // 1，生成流水号
        String connSeqNo = sequenceService.getPackageTaskNo();
        // 2,生成当前时间戳
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String curtime = df.format(new Date());

        //3,定义要回复的内容
        String jsonString;

        ExceptionRequest utils = new ExceptionRequest();
        String requestStr = JSON.toJSONString(request);
        if (requestStr == null) {
            log.info("请求报文不合法:requestStr为空");
            jsonString = utils.dataWeiKong(connSeqNo, curtime);
            return jsonString;
        } else {
            log.info("【ICCID验证登录】请求：" + requestStr);
            RequestUserLogin requestPackage = JSONArray.parseObject(requestStr, RequestUserLogin.class);
            String requestSign = requestPackage.getSign();
            if (requestPackage.getSign() == null) {
                log.info("请求报文不合法:sign为空");
                jsonString = utils.dataWeiKong(connSeqNo, curtime);
                return jsonString;
            } else {
                RequestUserLoginData requestData = requestPackage.getData();
                if (requestPackage.getData() == null) {
                    log.info("请求报文不合法:data为空");
                    jsonString = utils.dataWeiKong(connSeqNo, curtime);
                    return jsonString;
                } else {
                    String ConnSeqNo = requestData.getConnSeqNo();
                    String tradeTime = requestData.getTradeTime();
                    String tradeType = requestData.getTradeType();
                    String lang = requestData.getLang();
                    String version = requestData.getVersion();
                    RequestUserLoginTradeData requestTradeData = requestData.getTradeData();

                    if (StringUtils.isBlank(ConnSeqNo) || StringUtils.isBlank(tradeTime) || StringUtils.isBlank(tradeType) || lang == null || version == null || requestTradeData == null) {
                        log.info("请求报文不合法:data参数不合法");
                        jsonString = utils.dataWeiKong(connSeqNo, curtime);
                        return jsonString;
                    } else {
                        String deviceCode = requestTradeData.getDeviceCode();
                        String partnerScope = requestTradeData.getPartnerScope();

                        if (StringUtils.isBlank(deviceCode) || StringUtils.isBlank(partnerScope)) {
                            log.info("请求报文不合法:tradeData参数不合法");
                            jsonString = utils.dataWeiKong(connSeqNo, curtime);
                            return jsonString;
                        } else {

                            String str = JSON.toJSONString(requestData);
                            String sign = utils.calculateSignature(str);
                            log.info("计算的签名是：" + sign);

                            if (!requestSign.equalsIgnoreCase(sign)) {
                                if (lang.equals("en") || StringUtils.isBlank(lang)) {
                                    jsonString = utils.signatureFailure(ConnSeqNo, tradeTime, tradeType, "0001", "The signature is wrong, please confirm the signature!");
                                    return jsonString;
                                } else {
                                    jsonString = utils.signatureFailure(ConnSeqNo, tradeTime, tradeType, "0001", "签名有误,请确认签名!");
                                    return jsonString;
                                }
                            } else {//开始判断是cn还是en

                                if (lang.equals("cn") || StringUtils.isBlank(lang)) {

                                    //用deviceCode去iot网关查询企业编码
                                    UserLoginResponse partner = QueryPartnerCode(deviceCode.trim());

                                    if (null != partner && true == Constant.RET_CODE_0000.equalsIgnoreCase(partner.getRetCode())) {

                                        if (StringUtils.isNotBlank(partner.getPartnerCode())) {

                                            if (partner.getPartnerCode().equals("0")) {
                                                //不管查询到的渠道编码是不是跟请求上来的一致，我们都用新的渠道编码返回给前端，做覆盖
                                                jsonString = utils.returnsPublic(ConnSeqNo, partner.getPartnerCode(), curtime, tradeType, "9999", "无效卡片");
                                                log.info("【ICCID验证登录】系领之飞卡提示“无效卡片”：" + jsonString);
                                                return jsonString;
                                            } else {
                                                String secret = partnerInfoService.getSecretByPartnerCode(partner.getPartnerCode());

                                                //查询下设备的状态，为了屏蔽掉已废弃的卡片订购套餐。
                                                ResponseQueryDeviceRealTime device = QueryDevice(deviceCode.trim(), partner.getPartnerCode(), secret);

                                                boolean b1 = null != device && true == Constant.RET_CODE_0000.equals(device.getRetCode()) &&
                                                        null != device.getTradeData() && device.getTradeData().size() > 0 && !device.getTradeData().isEmpty();

                                                if (b1) {

                                                    for (ResponseQueryDeviceRealTimeTradeData tr : device.getTradeData()) {

                                                        boolean b2 = StringUtils.isNotBlank(tr.getLifecycle()) && (tr.getLifecycle().equals("4") || tr.getLifecycle().equals("5"));

                                                        if (b2) {
                                                            //卡片过期了，不允许成功登录
                                                            //不管查询到的渠道编码是不是跟请求上来的一致，我们都用新的渠道编码返回给前端，做覆盖
                                                            jsonString = utils.returnsPublic(ConnSeqNo, partner.getPartnerCode(), curtime, tradeType, "9999", "SIM卡已过期");
                                                            log.info("【ICCID验证登录】卡片已过期：" + jsonString);
                                                            return jsonString;

                                                        } else {
                                                            //卡片未过期可以支持登录订购套餐
                                                            //不管查询到的渠道编码是不是跟请求上来的一致，我们都用新的渠道编码返回给前端，做覆盖
                                                            jsonString = utils.returnsPublic(ConnSeqNo, partner.getPartnerCode(), curtime, tradeType, "0000", "登录成功");
                                                            log.info("【ICCID验证登录】成功响应：" + jsonString);
                                                            return jsonString;
                                                        }
                                                    }
                                                } else {//查询设备出现问题：
                                                    if (StringUtils.isNotBlank(device.getRetCode())) {
                                                        jsonString = utils.returnsPublic(ConnSeqNo, partner.getPartnerCode(), curtime, tradeType, device.getRetCode(), device.getResultInfo());
                                                        log.info("【ICCID验证登录】查询设备返回有误：" + jsonString);
                                                        return jsonString;
                                                    } else {
                                                        jsonString = utils.returnsPublic(ConnSeqNo, partner.getPartnerCode(), curtime, tradeType, "9999", "响应异常");
                                                        log.info("【ICCID验证登录】查询设备程序有误：" + jsonString);
                                                        return jsonString;
                                                    }

                                                }
                                            }
                                        } else {
                                            jsonString = utils.returnsPublic(ConnSeqNo, partner.getPartnerCode(), curtime, tradeType, "9998", "请输入有效的ICCID");
                                            log.info("【ICCID验证登录】返回时渠道编码为空：" + jsonString);
                                            return jsonString;
                                        }


                                    } else {//查询渠道编码出现问题：
                                        if (StringUtils.isNotBlank(partner.getRetCode())) {
                                            jsonString = utils.returnsPublic(ConnSeqNo, partner.getPartnerCode(), curtime, tradeType, partner.getRetCode(), partner.getResultInfo());
                                            log.info("【ICCID验证登录】查询渠道编码返回有误：" + jsonString);
                                            return jsonString;
                                        } else {
                                            jsonString = utils.returnsPublic(ConnSeqNo, partner.getPartnerCode(), curtime, tradeType, "9999", "响应异常");
                                            log.info("【ICCID验证登录】查询渠道编码程序有误：" + jsonString);
                                            return jsonString;
                                        }

                                    }


                                } else {//英文版


                                    //用deviceCode去iot网关查询企业编码
                                    UserLoginResponse partner = QueryPartnerCode(deviceCode.trim());

                                    if (null != partner && true == Constant.RET_CODE_0000.equalsIgnoreCase(partner.getRetCode())) {

                                        if (StringUtils.isNotBlank(partner.getPartnerCode())) {

                                            if (partner.getPartnerCode().equals("0")) {
                                                //不管查询到的渠道编码是不是跟请求上来的一致，我们都用新的渠道编码返回给前端，做覆盖
                                                jsonString = utils.returnsPublic(ConnSeqNo, partner.getPartnerCode(), curtime, tradeType, "9999", "Invalid Card");
                                                log.info("【ICCID验证登录】系领之飞卡提示“无效卡片”：" + jsonString);
                                                return jsonString;
                                            } else {
                                                String secret = partnerInfoService.getSecretByPartnerCode(partner.getPartnerCode());

                                                //查询下设备的状态，为了屏蔽掉已废弃的卡片订购套餐。
                                                ResponseQueryDeviceRealTime device = QueryDevice(deviceCode.trim(), partner.getPartnerCode(), secret);

                                                boolean b1 = null != device && true == Constant.RET_CODE_0000.equals(device.getRetCode()) &&
                                                        null != device.getTradeData() && device.getTradeData().size() > 0 && !device.getTradeData().isEmpty();

                                                if (b1) {

                                                    for (ResponseQueryDeviceRealTimeTradeData tr : device.getTradeData()) {

                                                        boolean b2 = StringUtils.isNotBlank(tr.getLifecycle()) && (tr.getLifecycle().equals("4") || tr.getLifecycle().equals("5"));

                                                        if (b2) {
                                                            //卡片过期了，不允许成功登录
                                                            //不管查询到的渠道编码是不是跟请求上来的一致，我们都用新的渠道编码返回给前端，做覆盖
                                                            jsonString = utils.returnsPublic(ConnSeqNo, partner.getPartnerCode(), curtime, tradeType, "9999", "The sim card has expired");
                                                            log.info("【ICCID验证登录】卡片已过期：" + jsonString);
                                                            return jsonString;

                                                        } else {
                                                            //卡片未过期可以支持登录订购套餐
                                                            //不管查询到的渠道编码是不是跟请求上来的一致，我们都用新的渠道编码返回给前端，做覆盖
                                                            jsonString = utils.returnsPublic(ConnSeqNo, partner.getPartnerCode(), curtime, tradeType, "0000", "success");
                                                            log.info("【ICCID验证登录】成功响应：" + jsonString);
                                                            return jsonString;
                                                        }
                                                    }
                                                } else {//查询设备出现问题：
                                                    if (StringUtils.isNotBlank(device.getRetCode())) {
                                                        jsonString = utils.returnsPublic(ConnSeqNo, partner.getPartnerCode(), curtime, tradeType, device.getRetCode(), "In response to abnormal");
                                                        log.info("【ICCID验证登录】查询设备返回有误：" + jsonString);
                                                        return jsonString;
                                                    } else {
                                                        jsonString = utils.returnsPublic(ConnSeqNo, partner.getPartnerCode(), curtime, tradeType, "9999", "In response to abnormal");
                                                        log.info("【ICCID验证登录】查询设备程序有误：" + jsonString);
                                                        return jsonString;
                                                    }

                                                }
                                            }
                                        } else {
                                            jsonString = utils.returnsPublic(ConnSeqNo, partner.getPartnerCode(), curtime, tradeType, "9998", "Please enter a valid ICCID");
                                            log.info("【ICCID验证登录】返回时渠道编码为空：" + jsonString);
                                            return jsonString;
                                        }


                                    } else {//查询渠道编码出现问题：
                                        if (StringUtils.isNotBlank(partner.getRetCode())) {
                                            jsonString = utils.returnsPublic(ConnSeqNo, partner.getPartnerCode(), curtime, tradeType, partner.getRetCode(), "Please enter a valid ICCID");
                                            log.info("【ICCID验证登录】查询渠道编码返回有误：" + jsonString);
                                            return jsonString;
                                        } else {
                                            jsonString = utils.returnsPublic(ConnSeqNo, partner.getPartnerCode(), curtime, tradeType, "9999", "In response to abnormal");
                                            log.info("【ICCID验证登录】查询渠道编码程序有误：" + jsonString);
                                            return jsonString;
                                        }

                                    }
                                }

                            }

                        }
                    }
                }
            }
        }
        return null;
    }

    /***
     * 查询设备实时信息：为了获得卡片是ota还是非ota
     * @param deviceCode
     * @param partnerCode
     * @param secret
     * @return
     */
    private ResponseQueryDeviceRealTime QueryDevice(String deviceCode, String partnerCode, String secret) {

        RequestQueryDeviceRealTimeNew deviceInfo = new RequestQueryDeviceRealTimeNew();
        deviceInfo.setDeviceId(deviceCode);
        deviceInfo.setPartnerCode(partnerCode);
        deviceInfo.setSecret(secret);
        //组装需要的json去请求报文
        String requestInterface = JSON.toJSONString(deviceInfo);
        log.info("查询【设备是否为OTA】请求：" + requestInterface);
        String url = requestURI + Constant.iot_queryDeviceRealTimeNew_2;

        // 发送post请求，并接收返回结果
        String returnStr = HttpUtil.httpPost(url, requestInterface);
        log.info("url=" + url + ";接口名：" + Constant.iot_queryDeviceRealTimeNew_2);

        log.info("查询【设备是否为OTA】响应：" + returnStr);
        return JSON.parseObject(returnStr, ResponseQueryDeviceRealTime.class);
    }

    /***
     *根据设备Iccid查询所属企业编码
     * @param deviceCode
     * @return
     */
    private UserLoginResponse QueryPartnerCode(String deviceCode) {

        UserLoginRequest user = new UserLoginRequest();
        user.setDeviceId(deviceCode);
        //组装需要的json去请求报文
        String requestInterface = JSON.toJSONString(user);
        log.info("【ICCID查询企业编码】请求：" + requestInterface);
        String url = requestURI + Constant.iot_queryPartner_2;

        // 发送post请求，并接收返回结果
        String returnStr = HttpUtil.httpPost(url, requestInterface);
        log.info("url=" + url);

        log.info("【ICCID查询企业编码】响应：" + returnStr);
        return JSON.parseObject(returnStr, UserLoginResponse.class);
    }


}